#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: crud.py
# @time: 2021/4/12 13:25
# @desc:
import json
from datetime import datetime
from typing import List, Dict, Optional
from fastapi import Request

from models.queryModels import MultipleConditionQueryHistoryParts
from utils.mongo_tools import retrieve_all_mongo_values, retrieve_one_mongo_value
from views.configs import HISTORY_PART_COLLECTION, MONGO_DATABASE_NAME, CATPART_OSS_ADDRESS, JSON_OSS_ADDRESS, PART_TYPE_COLLECTION
from views.tag import partTagInit


def keyword_search_history_part(
        queryModel: MultipleConditionQueryHistoryParts,
        result: list,
) -> list:
    """
    列表查询多条历史夹具或历史零件。

    :param queryModel: 前端传过来的参数，原封不动地传过来。
    :param result: 事先从历史夹具的数据库中把所有数据都取出来，以供搜索使用。
    """
    filtered_result = []
    for i in result:
        i_time = datetime.strptime(i["time"], "%Y-%m-%d %H:%M")
        # 按关键字查询
        if queryModel.keyword is None or queryModel.keyword.lower() in i["number"].lower() or queryModel.keyword.lower() in i["name"].lower():
            if queryModel.isAbstract is None or not queryModel.isAbstract or queryModel.isAbstract == i['isAbstract']:
                if queryModel.isFlag is None or not queryModel.isFlag or queryModel.isFlag == i['isFlag']:
                    if queryModel.isFeature is None or not queryModel.isFeature or queryModel.isFeature == i['isFeature']:
                        if queryModel.standard is None or queryModel.standard in i['tag']['standard']:
                            if queryModel.startTime is None or queryModel.startTime < i_time:
                                if queryModel.endTime is None or i_time < queryModel.endTime:
                                    if queryModel.version is None or queryModel.version == i['tag']['version']:
                                        if queryModel.partType is None or queryModel.partType in [level['number'] for level in i['tag']["partType"]]:
                                            filtered_result.append(i)

    return sorted(filtered_result, key=lambda x: x["name"])


def take_out_part_type_recursively(part_type_number: str, part_type_list: List):
    part_type_list.append(part_type_number)
    part_type_data = retrieve_all_mongo_values({"number": part_type_number}, collection_name=PART_TYPE_COLLECTION)[0]
    try:
        for i in part_type_data["children"]:
            part_type_list.append(i)
            take_out_part_type_recursively(i, part_type_list)
    except:
        pass


def query_history_part_config():
    # 先拿到所有的历史零件数据，取出里面的tag数据后再去重
    history_part = retrieve_all_mongo_values(
        filter_conditions={},
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )
    standard = []
    category = []
    bigType = []
    smallType = []
    for i in history_part:
        if i['tag']['standard'] is not None:
            standard.extend(i['tag']['standard'])
        if i['tag']['category'] is not None:
            category.append(i['tag']['category'])
        if i['tag']['bigType'] is not None:
            bigType.append(i['tag']['bigType'])
        if i['tag']['smallType'] is not None:
            smallType.append(i['tag']['smallType'])
    return {
        "standard": list(set(standard)),
        "category": list(set(category)),
        "bigType": list(set(bigType)),
        "smallType": list(set(smallType)),
    }


async def list_query_redis_cache(number_list: List[str], request: Request, database_name: str = MONGO_DATABASE_NAME, collection_name: str = HISTORY_PART_COLLECTION):
    result = []
    for i in number_list:
        temp_item = await request.app.state.redis.get(i)
        if temp_item is None:
            # 去mongo中查询这个id的数据
            temp_result = retrieve_one_mongo_value(i, database_name=database_name, collection_name=collection_name)
            # 如果mongo里能查到这条数据再把它更新到redis中
            if len(temp_result) > 0:
                temp_item = temp_result[0]
                # 把mongo中查到的数据set到redis数据库中
                await request.app.state.redis.set(temp_item["number"], json.dumps(temp_item))
            else:
                # 若是走到这一步那说明不但redis里没有，连mongo里面也没有这个number的数据了，就跳过append吧
                continue
        else:
            temp_item = json.loads(temp_item)
        result.append(temp_item)


def generate_history_part_data(
        number: str,
        file_path: str,
        json_path: str,
        desc: str = "",
        version: str = "暂无",
        isFeature: bool = False,
        isFlag: bool = False,
) -> Dict:
    """

    Args:
        number:
        file_path:
        json_path:
        desc:
        version:
        isFeature:
        isFlag:

    Returns:

    """
    model = {
        "number": number,
        "time": datetime.now().strftime("%Y-%m-%d %H:%M"),
        # 存到数据库的name字段只应当包含最后一层的名字
        "name": file_path.split("/")[-1],
        "desc": desc,
        "type": "2",
        "version": version,
        "isFeature": isFeature,
        "isFlag": isFlag,
        "tag": partTagInit(),
        "file": {
            CATPART_OSS_ADDRESS: file_path,
            JSON_OSS_ADDRESS: json_path,
            "transferFormatMessage": "not transfered yet",
        },
    }

    return model
